package com.jeomo.mem.starter.timedtask;

import com.jeomo.common.core.exception.BusinessException;
import com.jeomo.common.quartz.starter.service.BaseJob;
import com.jeomo.masterdata.starter.entity.Level;
import com.jeomo.masterdata.starter.mapper.LevelMapper;
import com.jeomo.mem.starter.entity.MemberCard;
import com.jeomo.mem.starter.entity.MemberLevelExe;
import com.jeomo.mem.starter.enums.MemLevelSrcTypeEnum;
import com.jeomo.mem.starter.mapper.MemberCardMapper;
import com.jeomo.mem.starter.mapper.MemberLevelExeMapper;
import com.jeomo.mem.starter.service.IMemberCardService;
import com.jeomo.mem.starter.service.impl.MemberLevelExeService;
import org.quartz.JobExecutionContext;
import org.quartz.JobExecutionException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.annotation.Resource;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.List;

/**
 * 评定会员级别任务;<br/>
 * 会员卡的等级到期后根据规则保级或者降级
 * 每天零点执行
 * @author:Jackpot
 * @create 2021-01-14 10:58
 * @description:
 */
public class RatingMemberLevelJob implements BaseJob {

    private Logger logger = LoggerFactory.getLogger(this.getClass());

    @Resource
    private MemberCardMapper memberCardMapper;
    @Resource
    private IMemberCardService memberCardService;
    @Resource
    private MemberLevelExeMapper memberLevelExeMapper;
    @Resource
    private LevelMapper levelMapper;
    @Resource
    private MemberLevelExeService memberLevelExeService;

    @Override
    public void execute(JobExecutionContext context) throws JobExecutionException {

        List<Level> allLevels = levelMapper.getAllLevels();
        List<MemberCard> memberCards = memberCardMapper.queryAllMemCards();
        int memberCardNum = memberCards.size();
        logger.info("自动处理到期的会员等级, 共计 "+memberCardNum+" 条会员信息 ");
        LocalDateTime now = LocalDateTime.now();
        int i =0;
        for (MemberCard memberCard : memberCards) {
            i += autoRatingMemberLeve(memberCard,now,allLevels);
        }
        logger.info("[会员等级到期自动处理]任务执行完毕, 实际处理 "+i+" 条信息.");
    }

    /**
     * 自动评定
     * @param memberCard
     * @param now
     * @return
     */
    public int autoRatingMemberLeve(MemberCard memberCard, LocalDateTime now,List<Level> allLevels){

        String org = memberCard.getOrg();
        String cardNo = memberCard.getCardNo();
        String memLevel = memberCard.getMemLevel();
        Level curLevel = getLevel(allLevels, memLevel);
        if (curLevel==null){
            logger.error("卡号为["+cardNo+"]的会员卡无法匹配对应的等级,请检查!");
            return 0;
        }
        Integer remainLevelSumBonus = curLevel.getRemainLevelSumBonus();
        Double remainLevelSumAmount = curLevel.getRemainLevelSumAmount();
        MemberLevelExe memberLevelExe = memberLevelExeMapper.queryUntreatedLevelExe(cardNo, memLevel);
        if (memberLevelExe==null){
            logger.error("卡号为["+cardNo+"]的会员卡无法匹配对应的执行单信息,请检查!");
            return 0;
        }
        if (memberLevelExe.getRating()) return 0;//已经评定完级别
        LocalDate endTime = memberLevelExe.getEndTime();
        if (now.toLocalDate().compareTo(endTime)<= 0) return 0;//会员等级还没有到期
        //处理:已经到期,并且没有评定级别的执行数据
        Integer totalPoints = memberLevelExe.getTotalPoints();
        Double totalAmount = memberLevelExe.getTotalAmount();
        Level newLevel = curLevel;
        int srcType = 0;
        if (totalPoints < remainLevelSumBonus && totalAmount < remainLevelSumAmount){//降级
            Level prevLevel = levelMapper.getPrevLevel(org, curLevel.getLevelCode());
            if (prevLevel!=null){//1.降级
                newLevel = prevLevel;
                memberCardMapper.updateCardLevel(cardNo,prevLevel.getCode());
                srcType= MemLevelSrcTypeEnum.DOWN.getCode();
            }else{//2.已经为最低级,无法降级,相当于保级
                srcType= MemLevelSrcTypeEnum.UN_CHANGE.getCode();
            }
        }
        if (totalPoints>=remainLevelSumBonus || totalAmount >= remainLevelSumAmount){//3.保级
            srcType= MemLevelSrcTypeEnum.UN_CHANGE.getCode();
        }
        //更新会员等级执行信息
        memberLevelExe.setRating(true);
        int i = memberLevelExeMapper.updateById(memberLevelExe);
        if (i!=1) throw new BusinessException("更新会员等级执行信息失败!");
        //会员等级到期,无论是保级还是降级,都要初始化一条新的执行信息
        Integer effectiveDay = newLevel.getEffectiveDay();
        LocalDate newEndTime = now.plusDays(effectiveDay).toLocalDate();
        memberLevelExeService.initLevelExe(cardNo,newLevel.getCode(),now,newEndTime,srcType);
        return 1;
    }

    public Level getLevel(List<Level> allLevels, String levelCode){
        for (Level level : allLevels) {
            if (level.getCode().equals(levelCode)) return level;
        }
        return null;
    }
}
